package update_optimize_account

import (
	"adam2/internal/model"
	"anubis-framework/pkg/io"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
	"math/big"
)

// 在卖出之后更新optimize_account
type UpdateOptimizeAccountAfterSell struct {
	db *gorm.DB
}

// 初始化
func (u *UpdateOptimizeAccountAfterSell) Init(db *gorm.DB) {
	u.db = db
}

// 在卖出之后更新optimize_account
func (u *UpdateOptimizeAccountAfterSell) Exec(transactionDate string) {
	io.Infoln("在卖出之后更新optimize_account")

	// 返回量化账户
	var optimizeAccountArray model.OptimizeAccountArray
	u.db.Table("optimize_account").Select("*").Order("id_ asc").Find(&optimizeAccountArray)

	for _, optimizeAccount := range optimizeAccountArray {
		// 持有股票的资产
		var holdStockAssets float64 = 0
		// 卖出股票的资产
		var sellStockAssets float64 = 0
		// 持股数量
		var sellOrBuyStockNumber int = 0

		// 计算每一个优化账户，在某一天卖完股票后持有股票的资产
		var optimizeStockTransactRecordArray model.OptimizeStockTransactRecordArray
		u.db.Raw("select * from optimize_stock_transact_record qstr "+
			"where qstr.account_name = ? "+
			"and qstr.sell_date is null and qstr.sell_price is null and qstr.sell_amount is null",
			(*optimizeAccount).AccountName).Scan(&optimizeStockTransactRecordArray)
		for _, optimizeStockTransactRecord := range optimizeStockTransactRecordArray {
			// 查找某只股票在某一天的开盘价
			var currentClosePrice float64 = 0
			u.db.Raw("select t.close_price from stock_transaction_data_all t "+
				"where t.code_ = ? and t.date_ = to_date(?, 'yyyy-mm-dd')",
				(*optimizeStockTransactRecord).StockCode, transactionDate).Scan(&currentClosePrice)

			if currentClosePrice == 0 {
				// 如果在某一天没有开盘价，比如停牌，则查找最近一个交易日的开盘价
				u.db.Raw("select std.close_price from ("+
					"select * from stock_transaction_data_all t where t.code_ = ? "+
					"and t.date_ < to_date(?, 'yyyy-mm-dd') "+
					"order by t.date_ desc) std where rownum <= 1",
					(*optimizeStockTransactRecord).StockCode, transactionDate).Scan(&currentClosePrice)
			}

			// 卖完股票后持有股票的资产、持股数量
			decimalValue := decimal.NewFromFloat(currentClosePrice)
			decimalValue = decimalValue.Mul(decimal.NewFromInt(int64(optimizeStockTransactRecord.BuyAmount)))
			res, _ := decimalValue.Float64()
			holdStockAssets = holdStockAssets + res
			sellOrBuyStockNumber = sellOrBuyStockNumber + 1
		}

		// 计算每一个优化账户，在某一天卖完股票后卖出股票的资产
		var _optimizeStockTransactRecordArray model.OptimizeStockTransactRecordArray
		u.db.Raw("select * from optimize_stock_transact_record qstr "+
			"where qstr.account_name = ? and qstr.sell_date=to_date(?, 'yyyy-mm-dd') "+
			"and qstr.sell_date is not null and qstr.sell_price is not null and qstr.sell_amount is not null",
			(*optimizeAccount).AccountName, transactionDate).Scan(&_optimizeStockTransactRecordArray)
		for _, optimizeStockTransactRecord := range _optimizeStockTransactRecordArray {
			// 查找某只股票在某一天的开盘价
			var currentClosePrice float64 = 0
			u.db.Raw("select t.close_price from stock_transaction_data_all t "+
				"where t.code_ = ? and t.date_ = to_date(?, 'yyyy-mm-dd')",
				(*optimizeStockTransactRecord).StockCode, transactionDate).Scan(&currentClosePrice)

			if currentClosePrice == 0 {
				// 如果在某一天没有开盘价，比如停牌，则查找最近一个交易日的开盘价
				u.db.Raw("select std.close_price from ("+
					"select * from stock_transaction_data_all t where t.code_ = ? "+
					"and t.date_ < to_date(?, 'yyyy-mm-dd') "+
					"order by t.date_ desc) std where rownum <= 1",
					(*optimizeStockTransactRecord).StockCode, transactionDate).Scan(&currentClosePrice)
			}

			// 卖完股票后卖出股票的资产
			_decimalValue := decimal.NewFromFloat(currentClosePrice)
			_decimalValue = _decimalValue.Mul(decimal.NewFromInt(int64(optimizeStockTransactRecord.BuyAmount)))
			_res, _ := _decimalValue.Float64()
			_a := new(big.Rat).SetFloat64(sellStockAssets)
			_b := new(big.Rat).SetFloat64(_res)
			sellStockAssets, _ = new(big.Rat).Add(_a, _b).Float64()

		}

		// 更新optimize_account表
		u.db.Exec("update optimize_account t "+
			"set t.hold_stock_number = ?, t.stock_assets = ?, t.capital_assets = round(t.capital_assets + ?, 4), t.total_assets = round(? + ? + ?, 4), "+
			"t.total_stamp_duty = (select COALESCE(sum(t1.stamp_duty), 0) from optimize_stock_transact_record t1 where t1.account_name = ?), "+
			"t.total_registrate_fee_when_sell = (select COALESCE(sum(t1.registration_fee_when_sell), 0) from optimize_stock_transact_record t1 where t1.account_name = ?), "+
			"t.total_commission_when_sell = (select COALESCE(sum(t1.commission_when_sell), 0) from optimize_stock_transact_record t1 where t1.account_name = ?) "+
			"where t.account_name = ?", sellOrBuyStockNumber, holdStockAssets, sellStockAssets,
			holdStockAssets, (*optimizeAccount).CapitalAssets, sellStockAssets,
			(*optimizeAccount).AccountName, (*optimizeAccount).AccountName, (*optimizeAccount).AccountName, (*optimizeAccount).AccountName)
	}
}
